#pragma once
#include <string>
#include "stringconverter.h"

namespace org
{
	namespace spark
	{
		namespace math
		{


			/// <summary>
			/// Represents a rational number
			/// @author Monad
			/// 
			/// </summary>
			class RationalNumber 
			{
				/* Serial version UID */
			private:
				//static const long long serialVersionUID = -7438309292079517592LL;

			public:
				static RationalNumber *const ZERO;
				static RationalNumber *const ONE;

				/* Parts of a rational number */
			private:
				long long numerator, denominator;


				/// <summary>
				/// Creates a rational number with given numerator
				/// and denominator </summary>
				/// <param name="numerator"> </param>
				/// <param name="denominator"> if denominator == 0, then it is ignored
				/// (it is considered to be 1) </param>
			public:
				RationalNumber(long long numerator, long long denominator);


				/// <summary>
				/// Creates a copy of the given rational number </summary>
				/// <param name="r"> </param>
				RationalNumber(RationalNumber *r);


				/// <summary>
				/// Creates a rational representation of an integer </summary>
				/// <param name="n"> </param>
				RationalNumber(long long n);


				RationalNumber(double n);


				/// <summary>
				/// Adds the rational number 'b' to this rational number
				/// Result is saved in this rational number </summary>
				/// <param name="b">
				/// @return </param>
				virtual RationalNumber *add(RationalNumber *b);


				/// <summary>
				/// Subtracts 'b' from the rational number </summary>
				/// <param name="b">
				/// @return </param>
				virtual RationalNumber *sub(RationalNumber *b);


				/// <summary>
				/// Divides the number by 'b' </summary>
				/// <param name="b">
				/// @return </param>
				virtual RationalNumber *div(RationalNumber *b);

				/// <summary>
				/// Multiplies the rational number by 'b'
				/// Result is saved in this rational number </summary>
				/// <param name="b">
				/// @return </param>
				virtual RationalNumber *mul(RationalNumber *b);


				/// <summary>
				/// Normalizes the number
				/// </summary>
			private:
				void normalize();

				/* Implementation of Number class */
			public:
				virtual double doubleValue();

				virtual float floatValue();

				virtual int intValue();

				virtual long long longValue();

				/// <summary>
				/// Compares two rational numbers
				/// </summary>
				virtual int compareTo(RationalNumber *o);


				virtual std::string ToString();

				virtual int GetHashCode();


				/// <summary>
				/// Parses the given string and returns the coded rational number </summary>
				/// <param name="str">
				/// @return </param>
				static RationalNumber *parse(const std::string &str);

			};

		}
	}
}

//----------------------------------------------------------------------------------------
//	
//	
//
//	This class is used to replace some conversions to or from strings.
//----------------------------------------------------------------------------------------
#include <sstream>

class StringConverterHelpery
{
public:
	template<typename T>
	static std::string toString(const T &subject)
	{
		std::stringstream ss;
		ss << subject;
		return ss.str();
	}

	template<typename T>
	static T fromString(const std::string &subject)
	{
		std::stringstream ss(subject);
		T target;
		ss >> target;
		return target;
	}
};